package com.xbongbong.crm.perform.query.list.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmListQryService;
import com.xbongbong.crm.handle.analysis.CompetitorListAnalysisDataHandler;
import com.xbongbong.crm.perform.query.list.button.ArchivedTag;
import com.xbongbong.crm.perform.query.list.button.PublicTag;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.DepartmentVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.HandleExplainHelp;
import com.xbongbong.parent.pojo.list.ConditionListPojo;
import com.xbongbong.parent.pojo.list.ConditionListResultPoJo;
import com.xbongbong.parent.pojo.list.DataAnalysisListPojo;
import com.xbongbong.parent.pojo.list.FieldListPojo;
import com.xbongbong.parent.pojo.list.PermissionListPojo;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.constant.RangeScreenConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.TagEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CompetitorEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.subform.CompetitorTeamEnum;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.model.DepartmentModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author gaojie
 * @version v1.0
 * @date 2022/9/16 14:11
 * @description
 */
@Service("competitorListServiceImpl")
public class CompetitorListServiceImpl extends AbstractCrmListQryService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CompetitorListServiceImpl.class);

    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private HandleExplainHelp handleExplainHelp;
    @Resource
    private CompetitorListAnalysisDataHandler competitorListAnalysisDataHandler;
    @Resource
    private DepartmentModel departmentModel;



    @Override
    public List<Integer> businessType() {
        return Collections.singletonList(XbbRefTypeEnum.COMPETITOR.getCode());
    }

    @Override
    public List<ConditionsEntityExt> getPermission(PermissionListPojo permissionListPojo) throws XbbException {
        // 竞争对手不在这里做权限查询条件，在下面的getCondition做，方便去封装should查询条件
        return new ArrayList<>();
    }

    @Override
    public ConditionListResultPoJo getCondition(ConditionListPojo conditionListPojo) throws XbbException {
        try {
            // pc端 com.xbongbong.saas.help.SaasListHelp.commonFilter
            webCommonFilter(conditionListPojo);
            // 更改下条件的attr
            changeAttrForRange(conditionListPojo);
            // 公共条件封装
            commonCondition(conditionListPojo);
            // 封装权限条件
            getPermissionListCondition(conditionListPojo);
            return new ConditionListResultPoJo(conditionListPojo.getConditionList(),conditionListPojo.getShouldConditionList());
        }catch (Exception e){
            LOGGER.error("com.xbongbong.crm.list.CompetitorListServiceImpl.getCondition error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }


    private void getPermissionListCondition(ConditionListPojo conditionListPojo){
        UserVO userVO = conditionListPojo.getUserVO();
        List<ConditionsEntityExt> conditionList = new ArrayList<>();
        if (userVO.isMaxDataPermission()) {
            return ;
        }
        List<ConditionsEntityExt> permissionList = getDepAndUserPermission(userVO);
        List<List<ConditionsEntityExt>> shouldConditionList = conditionListPojo.getShouldConditionList();
        for (ConditionsEntityExt permission : permissionList) {
            shouldConditionList.add(Arrays.asList(permission));
        }
    }

    /**
     * 将范围  条件的attr转化为可见人或可见部门attr
     * @param conditionListPojo
     */
    private void changeAttrForRange(ConditionListPojo conditionListPojo){
        JSONObject commonFilter = conditionListPojo.getCommonFilter();
        if (commonFilter == null){
            return;
        }
        JSONObject rangeScreen = commonFilter.getJSONObject(RangeScreenConstant.RANGE_SCREEN);
        if (Objects.isNull(rangeScreen) || Objects.isNull(rangeScreen.get(RangeScreenConstant.TYPE)) || StringUtil.isEmpty(rangeScreen.getString(RangeScreenConstant.TYPE)) || Objects.isNull(rangeScreen.get(RangeScreenConstant.VALUE))) {
            return;
        }
        String type = rangeScreen.getString(RangeScreenConstant.TYPE);
        List<ConditionsEntityExt> conditionList = conditionListPojo.getConditionList();
        if (CollectionsUtil.isNotEmpty(conditionList)){
            List<ConditionsEntityExt> visiableRangeList = conditionList.stream().filter(item -> Objects.equals(item.getAttr(), RangeScreenConstant.VISIABLE_RANGE)).collect(Collectors.toList());
            if (CollectionsUtil.isNotEmpty(visiableRangeList)){
                ConditionsEntityExt entityExt = visiableRangeList.get(0);
                if (Objects.equals(type,RangeScreenConstant.USER)){
                    entityExt.setAttr(CompetitorEnum.VISBLE_USER.getAttr());
                }else if (Objects.equals(type,RangeScreenConstant.DEPARTMENT)){
                    entityExt.setAttr(CompetitorEnum.VISBLE_DEPT.getAttr());
                }
            }
        }
    }

    @Override
    public ConditionListResultPoJo mobileGetCondition(ConditionListPojo conditionListPojo) throws XbbException {
        try {
            String corpid = conditionListPojo.getCorpid();
            Long formId = conditionListPojo.getFormId();
            List<ConditionsEntityExt> conditions = conditionListPojo.getConditionList();
            //  手机端条件封装
            saasListDataPermissionHelp.dingtalkRangeScreen(conditions, conditionListPojo.getUserVO(), XbbRefTypeEnum.COMPETITOR.getCode(), conditionListPojo.getSubBusinessType(), conditionListPojo.getPlatform());
            // 公共条件封装
            commonCondition(conditionListPojo);
            // 封装权限条件
            getPermissionListCondition(conditionListPojo);
            return new ConditionListResultPoJo(conditionListPojo.getConditionList(), conditionListPojo.getShouldConditionList());
        } catch (Exception e) {
            LOGGER.error("com.xbongbong.crm.list.CustomerListServiceImpl.getCondition error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public HandleExplainPojo getExplain(FieldListPojo fieldListPojo) throws XbbException {
        try {
            List<String> fieldList = new ArrayList();
            List<FieldAttrEntity> explainList = commonGetExplain(fieldListPojo, fieldList);
            Iterator<FieldAttrEntity> iterator = explainList.iterator();
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO(explainList, fieldListPojo.getForm(), fieldListPojo.getCorpid(), fieldListPojo.getUserVO().getUserId(), fieldListPojo.getUserVO(), true, fieldListPojo.getSubBusinessType());
            HandlerExplainVO handlerExplainVO = handleExplainHelp.handleExplain(handlerExplainDTO);

            HandleExplainPojo handleExplainPojo = new HandleExplainPojo();
            explainList = handlerExplainVO.getHeadList();
            handleExplainPojo.setExplainList(explainList);
            handleExplainPojo.setFieldList(fieldList);

            return handleExplainPojo;
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("com.xbongbong.crm.list.CompetitorListServiceImpl.getExplain error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public List<PaasFormDataEntityExt> webDataAnalysis(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        try {
            String corpid = dataAnalysisListPojo.getCorpid();
            List<PaasFormDataEntityExt> formDataList = dataAnalysisListPojo.getFormDataList();

            FormDataListDTO formDataListDTO = new FormDataListDTO(dataAnalysisListPojo.getCorpid(), dataAnalysisListPojo.getFormId(), dataAnalysisListPojo.getSaasMark(), dataAnalysisListPojo.getBusinessType(), dataAnalysisListPojo.getSubBusinessType(), dataAnalysisListPojo.getDistributorMark(), dataAnalysisListPojo.getUserVO(), dataAnalysisListPojo.getAnalysisAmountOfThousandBitsWithOriginalValue(), dataAnalysisListPojo.getPage(), dataAnalysisListPojo.getPageSize());
            PaasFormDataEsListVO formDataListVO = new PaasFormDataEsListVO();
            formDataListVO.setPaasFormDataESList(formDataList);
            formDataListVO.setHeadList(dataAnalysisListPojo.getExplainList());
            competitorListAnalysisDataHandler.analysisDataList(formDataListDTO,formDataListVO);

            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByList(dataAnalysisListPojo.getExplainList(), null);
            PaasFormDataEsListVO formDataEsListVO = new PaasFormDataEsListVO();
            formDataEsListVO.setExplainMap(explainMap);
            return formDataListVO.getPaasFormDataESList();
        } catch (Exception e) {
            LOGGER.error("com.xbongbong.crm.list.CustomerListServiceImpl.dataAnalysis error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public List<AppListPojo> dingtalkOperate(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {

        Integer subBusinessType = dataAnalysisListPojo.getSubBusinessType();
        List<AppListPojo> appListPojos = new ArrayList<>();

        List<PaasFormDataEntityExt> dataList =dataAnalysisListPojo.getFormDataList();
        Long formId = dataAnalysisListPojo.getFormId();
        Integer businessType = dataAnalysisListPojo.getBusinessType();
        List<Long> dataIdIn = new ArrayList<>();
        dataList.forEach(item->{
            dataIdIn.add(item.getId());
        });
        Set<String> userIdSet = new HashSet<>();
        Map<Long, List<String>> mainUserIdIn = new HashMap<>(dataIdIn.size());
        Map<Long, List<String>> coUserIdIn = new HashMap<>(dataIdIn.size());
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        handlerExplainDTO.setLoginUser(dataAnalysisListPojo.getUserVO());
        handlerExplainDTO.setUserId(dataAnalysisListPojo.getUserId());
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(dataAnalysisListPojo.getExplainList().size());
        dataAnalysisListPojo.getExplainList().forEach(item->{
            explainMap.put(item.getAttr(), item);
        });

        for (PaasFormDataEntityExt customer : dataList) {
            JSONObject data = customer.getData();
            Long customerId = customer.getDataId();
            Long dataId = customer.getDataId();
            Long appId = customer.getAppId();
            Long menuId = customer.getMenuId();
            String name = FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerManagementEnum.NAME.getAttr(), "");

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();

            List<SummaryDataPoJo> lableList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);

            // isAchived为1代表归档，2代表未归档
            if(Objects.equals(data.getInteger(CustomerManagementEnum.IS_ARCHIVED.getAttr()), 1)){
                superScript.put("archived", 1);
            }

            // 当前数据的创建人、负责人、协同人、当前操作人
            handlerExplainDTO.setOwnerId(mainUserIdIn.get(customerId));
            handlerExplainDTO.setCoUserId(coUserIdIn.get(customerId));
            handlerExplainDTO.setCreatorId(customer.getCreatorId());
            boolean stageOpen = CommonHelp.ifStageOpen(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), explainMap , handlerExplainDTO);

            if (stageOpen) {
                String customerStageStr = FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerManagementEnum.CUSTOMER_STAGE.getAttr(), "");
                if (!customerStageStr.isEmpty()) {
                    others.put("stage", customerStageStr);
                }
            }
            if(Objects.equals(XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(), subBusinessType)){
                others.put("isGrab",1);
            }
            boolean isShowCallCenterPhone = false;
            if (!Objects.equals(XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(), subBusinessType) || Objects.equals(XbbRefTypeEnum.CUSTOMER_DEAL.getCode(), subBusinessType)) {
                isShowCallCenterPhone = true;
            }
            //app系统关联数据展示需要 others 和 superScript
            data.put("others",others);
            data.put("superScript",superScript);
            appListPojos.add(new AppListPojo(customerId, titleList, summaryList, superScript, lableList, others, appId, menuId, formId, name,businessType,dataId));
        }
        return appListPojos;
    }

    @Override
    public void webOperate(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException{
        String corpid = dataAnalysisListPojo.getCorpid();
        String userId = dataAnalysisListPojo.getUserId();
        Integer subBusinessType = dataAnalysisListPojo.getSubBusinessType();
        List<PaasFormDataEntityExt> dataList =dataAnalysisListPojo.getFormDataList();
        List<FieldAttrEntity> list = dataAnalysisListPojo.getExplainList();
        List<Long> dataIdIn = new ArrayList<>();
        dataList.forEach(item->{
            dataIdIn.add(item.getId());
        });
        Set<String> userIdSet = new HashSet<>();
        Map<Long, List<String>> mainUserIdIn = new HashMap<>(dataIdIn.size());
        Map<Long, List<String>> coUserIdIn = new HashMap<>(dataIdIn.size());
        Boolean isPublic = Objects.equals(XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(),subBusinessType);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(dataAnalysisListPojo.getExplainList().size());
        String field = CustomerManagementEnum.NAME.getAttr();
        ArchivedTag archivedTagPojo = new ArchivedTag(field+"Tag");
        //客户公海池不显示退字标签
        PublicTag publicTagPojo = new PublicTag();
        PublicTag transferTagPojo = new PublicTag();
        dataAnalysisListPojo.getExplainList().forEach(item->{
            if (Objects.equals(item.getAttr(), field)) {
                item.setTagAttr(field + "Tag");
            }
            explainMap.put(item.getAttr(), item);
        });
        Integer businessType = dataAnalysisListPojo.getBusinessType();
        PublicTag finalPublicTagPojo = publicTagPojo;
        PublicTag finalTransferTagPojo = transferTagPojo;
        dataList.forEach(item->{
            JSONObject tagData = item.getTagData();
            JSONObject data = item.getData();
            // 设置“归档”状态
            ArchivedTag.setArchivedData(archivedTagPojo, tagData, Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) && Objects.equals(data.getInteger(CustomerManagementEnum.IS_ARCHIVED.getAttr()), 1), TagEnum.TAG_ARCHIVED);
        });
    }

    /**
     * 获取可见人可见部门权限
     * @param userVO
     * @return
     */
    protected List<ConditionsEntityExt> getDepAndUserPermission(UserVO userVO){
        List<ConditionsEntityExt> conditionList = new ArrayList<>();
        Set<DepartmentVO> depSet = userVO.getDepSet();
        List<Long> curDepIdIn = new ArrayList<>();
        depSet.stream().forEach(cur -> curDepIdIn.add(cur.getId()));
        List<String> depIn = new ArrayList<>();

        // 竞争对手角色为仅本人时，可见范围为 可见人 + 可见部门 + 可见部门的上级部门
        if (CollectionsUtil.isNotEmpty(curDepIdIn)) {
            List<Long> supDepIdList = departmentModel.getSupDepIdList(userVO.getCorpid(), curDepIdIn, true);
            curDepIdIn.stream().forEach(cur -> depIn.add(cur.toString()));
            supDepIdList.stream().forEach(sub -> depIn.add(sub.toString()));
        }

        //封装可见人筛选条件
        ConditionsEntityExt userCondition = new ConditionsEntityExt();
        userCondition.setAttr(CompetitorEnum.VISBLE_USER.getAttr());
        userCondition.setFieldType(CompetitorEnum.VISBLE_USER.getFieldType());
        userCondition.setSymbol(ConditionEnum.IN.getSymbol());
        userCondition.setValue(Collections.singletonList(userVO.getUserId()));
        userCondition.setTeamType(0);
        //封装可见部门筛选条件
        ConditionsEntityExt depCondition = new ConditionsEntityExt();
        depCondition.setAttr(CompetitorEnum.VISBLE_DEPT.getAttr());
        depCondition.setFieldType(CompetitorEnum.VISBLE_DEPT.getFieldType());
        depCondition.setSymbol(ConditionEnum.IN.getSymbol());
        depCondition.setValue(new ArrayList<>(depIn));
        depCondition.setTeamType(1);

        conditionList.add(userCondition);
        conditionList.add(depCondition);
        return conditionList;
    }

    private void commonCondition(ConditionListPojo conditionListPojo) throws XbbException {
        setCommonCondition(conditionListPojo);
    }
}
